package com.sh.business.controller;

import java.util.List;

import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.lang.tree.Tree;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.sh.business.domain.UserInvest;
import com.sh.business.domain.bo.OpenSafeBo;
import com.sh.business.domain.bo.SetComputilityBo;
import com.sh.business.domain.dto.DelayMessageDto;
import com.sh.business.domain.form.AirdropManualBo;
import com.sh.business.domain.form.ModifyParentBo;
import com.sh.business.domain.vo.BackendDataVo;
import com.sh.business.domain.vo.BackendUserVo;
import com.sh.business.domain.vo.BizUserImportVo;
import com.sh.business.listener.BizUserImportListener;
import com.sh.business.mapper.UserInvestMapper;
import com.sh.business.service.IUserInvestService;
import com.sh.business.service.facade.TransactionServiceFacade;
import com.sh.business.service.facade.UserFoundServiceFacade;
import com.sh.business.service.facade.UserServiceFacade;
import com.sh.common.core.enums.TransferStatusEnum;
import com.sh.common.excel.core.ExcelResult;
import com.sh.common.satoken.utils.LoginHelper;
import com.sh.system.domain.vo.SysUserVo;
import com.sh.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.sh.common.idempotent.annotation.RepeatSubmit;
import com.sh.common.log.annotation.Log;
import com.sh.common.web.core.BaseController;
import com.sh.common.mybatis.core.page.PageQuery;
import com.sh.common.core.domain.R;
import com.sh.common.core.validate.AddGroup;
import com.sh.common.core.validate.EditGroup;
import com.sh.common.log.enums.BusinessType;
import com.sh.common.excel.utils.ExcelUtil;
import com.sh.business.domain.vo.UserVo;
import com.sh.business.domain.bo.UserBo;
import com.sh.business.service.IUserService;
import com.sh.common.mybatis.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile;

/**
 * 用户信息
 *
 * @author ruoyi
 * @date 2024-10-09
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/business/user")
public class UserController extends BaseController {

    private final IUserService userService;
    private final ISysUserService iSysUserService;
    private final UserServiceFacade userServiceFacade;
    private final UserFoundServiceFacade userFoundServiceFacade;

    /**
     * 回收业绩
     */
    /*@SaCheckPermission("business:user:recycleComputility")
    @GetMapping("/recycleComputility/{orderSn}")
    public R<Void> recycleComputility(@PathVariable("orderSn") String orderSn) {
        userService.recycleComputility(orderSn);
        return R.ok();
    }*/

    /**
     * 重发奖励
     */
    /*@SaCheckPermission("business:user:handleInvestNotifyResend")
    @GetMapping("/handleInvestNotifyResend/{txHash}")
    public R<Void> handleInvestNotifyResend(@PathVariable("txHash") String txHash) {
        userServiceFacade.handleInvestNotifyResend(txHash);
        return R.ok();
    }*/

    /**
     * 补发静态
     */
    /*@SaCheckPermission("business:user:mingSzpnResend")
    @GetMapping("/mingSzpnResend")
    public R<Void> mingSzpnResend() {
        userServiceFacade.mingSzpnResend();
        return R.ok();
    }*/

    /**
     * 手动处理理财错误数据
     */
    /*@SaCheckPermission("business:user:handleUserFinancingError")
    @GetMapping("/handleUserFinancingError")
    public R<Void> handleUserFinancingError() {
        userService.handleUserFinancingError();
        return R.ok();
    }*/


    /**
     * 手动确认到账
     */
    @SaCheckPermission("business:user:handleConfirmReceipt")
    @GetMapping("/handleConfirmReceipt/{txHash}")
    public R<Void> handleConfirmReceipt(@PathVariable("txHash") String txHash) {
        userService.handleConfirmReceipt(txHash);
        return R.ok();
    }

    /**
     * 处理用户级别
     */
    @SaCheckPermission("business:user:handleSzpnUserLevel")
    @GetMapping("/handleSzpnUserLevel")
    public R<Void> handleSzpnUserLevel() {
        userServiceFacade.handleSzpnUserLevel(null);
        return R.ok();
    }

    /**
     * 修改推荐人
     */
    @SaCheckPermission("business:user:modifyParent")
    @PostMapping("/modifyParent")
    public R<Void> modifyParent(@RequestBody ModifyParentBo bo) {
        userService.modifyParent(bo.getUserId(), bo.getParentId());
        return R.ok();
    }

    /**
     * 查询用户信息列表
     */
    @SaCheckPermission("business:user:list")
    @GetMapping("/list")
    public TableDataInfo<UserVo> list(UserBo bo, PageQuery pageQuery) {
        return userService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出用户信息列表
     */
    @SaCheckPermission("business:user:export")
    @Log(title = "用户信息", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(UserBo bo, HttpServletResponse response) {
        List<UserVo> list = userService.queryList(bo);
        ExcelUtil.exportExcel(list, "用户信息", UserVo.class, response);
    }

    /**
     * 获取用户信息详细信息
     *
     * @param userId 主键
     */
    @SaCheckPermission("business:user:query")
    @GetMapping("/{userId}")
    public R<UserVo> getInfo(@NotNull(message = "主键不能为空")
                                     @PathVariable Long userId) {
        return R.ok(userService.queryById(userId));
    }

    /**
     * 新增用户信息
     */
    @SaCheckPermission("business:user:add")
    @Log(title = "用户信息", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody UserBo bo) {
        return toAjax(userService.insertByBo(bo));
    }

    /**
     * 二级认证
     */
    @Log(title = "二级认证", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @SaCheckPermission("business:orderRecycle:openSafe")
    @PostMapping("/openSafe")
    public SaResult openSafe(@Validated @RequestBody OpenSafeBo openSafeBo) {
        SysUserVo sysUserVo = iSysUserService.selectUserById(LoginHelper.getUserId());
        // 比对密码（此处只是举例，真实项目时可拿其它参数进行校验）
        if(BCrypt.checkpw(openSafeBo.getPassword(), sysUserVo.getPassword())) {
            // 比对成功，为当前会话打开二级认证，有效期为300秒[5分钟]
            StpUtil.openSafe(300);
            return SaResult.ok("二级认证成功");
        }
        // 如果密码校验失败，则二级认证也会失败
        return SaResult.error("二级认证失败");
    }

    /**
     * 划拨算力
     */
    @SaCheckPermission("business:user:setComputility")
    @Log(title = "划拨算力", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/setComputility")
    public SaResult setComputility(@Validated @RequestBody SetComputilityBo bo) {
        if (!StpUtil.isSafe()) {
            return SaResult.ok("0");
        }

        return userService.setComputility(bo) ? SaResult.ok() : SaResult.error();
    }

    /**
     * 人工空投
     */
    @SaCheckPermission("business:user:airdrop")
    @Log(title = "人工空投", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/airdropManual")
    public SaResult airdropManual(@Validated @RequestBody AirdropManualBo bo) {
        if (!StpUtil.isSafe()) {
            return SaResult.ok("0");
        }

        return userFoundServiceFacade.airdropManual(bo) ? SaResult.ok() : SaResult.error();
    }

    /**
     * 社区扶持
     */
    @SaCheckPermission("business:user:communitySupport")
    @Log(title = "社区扶持", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/communitySupport")
    public SaResult communitySupport(@Validated @RequestBody AirdropManualBo bo) {
        if (!StpUtil.isSafe()) {
            return SaResult.ok("0");
        }

        return userFoundServiceFacade.communitySupport(bo) ? SaResult.ok() : SaResult.error();
    }

    /**
     * 修改资产
     */
    @SaCheckPermission("business:user:修改资产")
    @Log(title = "修改资产", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/modifyAsset")
    public R<Void> modifyAsset(@Validated @RequestBody AirdropManualBo bo) {
        /*if (!StpUtil.isSafe()) {
            return SaResult.ok("0");
        }*/

        return toAjax(userFoundServiceFacade.modifyAsset(bo));
    }

    /**
     * 修改用户信息
     */
    @SaCheckPermission("business:user:edit")
    @Log(title = "用户信息", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public SaResult edit(@Validated(EditGroup.class) @RequestBody UserBo bo) {
        if (!StpUtil.isSafe()) {
            return SaResult.ok("0");
        }
        return userService.updateByBo(bo) ? SaResult.ok() : SaResult.error();
    }

    /**
     * 删除用户信息
     *
     * @param userIds 主键串
     */
    /*@SaCheckPermission("business:user:remove")
    @Log(title = "用户信息", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] userIds) {
        return toAjax(userService.deleteWithValidByIds(List.of(userIds), true));
    }*/

    /**
     * 查询统计信息
     *
     */
    @SaCheckPermission("business:user:queryDataVo")
    @GetMapping("/queryDataVo")
    public R<BackendDataVo> queryDataVo() {
        return R.ok(userService.queryDataVo());
    }

    /**
     * 查询用户地区数据
     *
     */
    @SaCheckPermission("business:user:queryUserVoList")
    @GetMapping("/queryUserVoList")
    public R<List<BackendUserVo>> queryUserVoList() {
        return R.ok(userService.queryUserVoList());
    }

    /**
     * 查询网体
     *
     */
    //@SaCheckPermission("business:user:queryNetBody")
    @SaIgnore
    @GetMapping("/queryNetBody")
    public R<List<Tree<Long>>> queryNetBody(@RequestParam(value = "userId",required = false,defaultValue = "10") String userId) {
        return R.ok(userService.queryNetBody(userId));
    }

    /**
     * 导入数据
     *
     * @param file          导入文件
     */
    @Log(title = "导入用户", businessType = BusinessType.IMPORT)
    @SaCheckPermission("business:user:import")
    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
        ExcelResult<BizUserImportVo> result = ExcelUtil.importExcel(file.getInputStream(), BizUserImportVo.class, new BizUserImportListener());
        return R.ok(result.getAnalysis());
    }

}
